package cn.com.nxt.txb;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.ksyun.media.player.IMediaPlayer;
import com.ksyun.media.player.KSYMediaMeta;
import com.ksyun.media.player.KSYMediaPlayer;
import com.ksyun.media.player.KSYTextureView;
import com.ksyun.media.player.misc.KSYQosInfo;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nimlib.sdk.avchat.constant.AVChatType;

import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import org.xutils.x;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import cn.com.nxt.txb.education.activity.ChatRoomActivity;
import cn.com.nxt.txb.httpdelegate.BillingDelegate;
import cn.com.nxt.txb.httpdelegate.DialingDelegate;
import cn.com.nxt.txb.util.AppConstant;
import cn.com.nxt.txb.util.AppUtil;


/**
 * Created by shichang on 9/23/16.
 */
@ContentView(R.layout.texture_player)
public class TextureVideoActivity extends BaseActivity implements HttpProtocol {
    private static final String TAG = "TextureVideoActivity";
    private Context mContext;
    KSYTextureView mVideoView = null;
    private Handler mHandler;
    private int mVideoWidth = 0;
    private int mVideoHeight = 0;
    public static String mRoomID;
    public static String mMeetingID;
    private boolean isRecord;
    private String mDataSource;
    private DialingDelegate dialingDelegate;
    @ViewInject(R.id.ll_statement)
    private LinearLayout mStatementLl;
    @ViewInject(R.id.ll_statement_cancel)
    private LinearLayout mStatementCancel;
    private BillingDelegate billingDelegate;
    private final byte GET_OTHER_NAME_MEETING = 0x26;
    private final byte SEND_RECORD = 0x27;


    private IMediaPlayer.OnPreparedListener mOnPreparedListener = new IMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(IMediaPlayer mp) {
            Log.d("VideoPlayer", "OnPrepared");
            mVideoWidth = mVideoView.getVideoWidth();
            mVideoHeight = mVideoView.getVideoHeight();
            // Set Video Scaling Mode
            mVideoView.setVideoScalingMode(KSYMediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
            //start player
            mVideoView.start();
            //set progress
        }
    };

    private IMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new IMediaPlayer.OnBufferingUpdateListener() {
        @Override
        public void onBufferingUpdate(IMediaPlayer mp, int percent) {
            //long duration = mVideoView.getDuration();
            // long progress = duration * percent / 100;
        }
    };

    private IMediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangeListener = new IMediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNum, int sarDen) {
            if (mVideoWidth > 0 && mVideoHeight > 0) {
                if (width != mVideoWidth || height != mVideoHeight) {
                    mVideoWidth = mp.getVideoWidth();
                    mVideoHeight = mp.getVideoHeight();

                    if (mVideoView != null)
                        mVideoView.setVideoScalingMode(KSYMediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
                }
            }
        }
    };

    private IMediaPlayer.OnSeekCompleteListener mOnSeekCompletedListener = new IMediaPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete(IMediaPlayer mp) {
            Log.e(TAG, "onSeekComplete...............");
        }
    };

    private IMediaPlayer.OnCompletionListener mOnCompletionListener = new IMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(IMediaPlayer mp) {
            Toast.makeText(mContext, "OnCompletionListener, play complete.", Toast.LENGTH_LONG).show();
            videoPlayEnd();
        }
    };

    private IMediaPlayer.OnErrorListener mOnErrorListener = new IMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(IMediaPlayer mp, int what, int extra) {
            switch (what) {
                //case KSYVideoView.MEDIA_ERROR_UNKNOWN:
                // Log.e(TAG, "OnErrorListener, Error Unknown:" + what + ",extra:" + extra);
                //  break;
                default:
                    Log.e(TAG, "OnErrorListener, Error:" + what + ",extra:" + extra);
            }

            videoPlayEnd();

            return false;
        }
    };

    public IMediaPlayer.OnInfoListener mOnInfoListener = new IMediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(IMediaPlayer iMediaPlayer, int i, int i1) {
            switch (i) {
                case KSYMediaPlayer.MEDIA_INFO_BUFFERING_START:
                    Log.d(TAG, "Buffering Start.");
                    break;
                case KSYMediaPlayer.MEDIA_INFO_BUFFERING_END:
                    Log.d(TAG, "Buffering End.");
                    break;
                case KSYMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START:
                    Toast.makeText(mContext, "Audio Rendering Start", Toast.LENGTH_SHORT).show();
                    break;
                case KSYMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    Toast.makeText(mContext, "Video Rendering Start", Toast.LENGTH_SHORT).show();
                    break;
                case KSYMediaPlayer.MEDIA_INFO_RELOADED:
                    Toast.makeText(mContext, "Succeed to reload video.", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "Succeed to mPlayerReload video.");
                    return false;
            }
            return false;
        }
    };

    private IMediaPlayer.OnMessageListener mOnMessageListener = new IMediaPlayer.OnMessageListener() {
        @Override
        public void onMessage(IMediaPlayer iMediaPlayer, String name, String info, double number) {
            Log.e(TAG, "name:" + name + ",info:" + info + ",number:" + number);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        x.view().inject(this);//注解绑定
        mContext = this.getApplicationContext();
        //setContentView(R.layout.texture_player);
        dialingDelegate = new DialingDelegate(this);
        mVideoView = (KSYTextureView) findViewById(R.id.texture_view);
        mVideoView.setKeepScreenOn(true);
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        mRoomID = getIntent().getStringExtra("roomid");
        mMeetingID = getIntent().getStringExtra("meetingid");
        mDataSource = getIntent().getStringExtra("path");
        isRecord = getIntent().getBooleanExtra("isRecord", false);
        if (isRecord)
            dialingDelegate.getOtherName(AppUtil.mUser.getToken(), mRoomID, GET_OTHER_NAME_MEETING);
        Log.e("--rtmp_url--11", mDataSource);
        mVideoView.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
        mVideoView.setOnCompletionListener(mOnCompletionListener);
        mVideoView.setOnPreparedListener(mOnPreparedListener);
        mVideoView.setOnInfoListener(mOnInfoListener);
        mVideoView.setOnVideoSizeChangedListener(mOnVideoSizeChangeListener);
        mVideoView.setOnErrorListener(mOnErrorListener);
        mVideoView.setOnSeekCompleteListener(mOnSeekCompletedListener);
        mVideoView.setOnMessageListener(mOnMessageListener);
        mVideoView.setScreenOnWhilePlaying(true);
        mVideoView.setBufferTimeMax(2);
        mVideoView.setBufferSize(15);
        mVideoView.setTimeout(5, 30);
//        if (chooseDecode.equals(Settings.USEHARD)) {
//            useHwCodec = true;
//        } else {
//            useHwCodec = false;
//        }
//        if (useHwCodec) {
//            //硬解264&265
//            Log.e(TAG, "Hardware !!!!!!!!");
//            mVideoView.setDecodeMode(KSYMediaPlayer.KSYDecodeMode.KSY_DECODE_MODE_AUTO);
//        }
        try {
            mVideoView.setDataSource(mDataSource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mVideoView.prepareAsync();
        bindService(new Intent(TextureVideoActivity.this, MQTTService.class), this, BIND_AUTO_CREATE);
        billingDelegate = new BillingDelegate(this);
        String param = AppUtil.getJoinMeetingParam(AppUtil.mUser.getPhone(), AppUtil.mUser.getUsername(), mMeetingID, mRoomID, 1, 3);
        SampleApplicationLike.joinOrExitMeeting(billingDelegate, AppUtil.mUser.getToken(), param);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //  timer.cancel();
        mVideoView = null;
        unbindService(this);
        mqttBinder.unsubscribe("/meetting/handspeak/resp/" + AppUtil.mUser.getPhone());
        //  NetStateUtil.unregisterNetState(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mVideoView != null) {
            mVideoView.runInBackground(true);
        }
        unregisterReceiver(mqttReceiver);
        //  NetStateUtil.registerNetState(this, netChangeListener);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mVideoView != null) {
            mVideoView.runInForeground();
        }
        //注册广播
        IntentFilter counterActionFilter = new IntentFilter(AppConstant.MQTT_AUDIT);
        registerReceiver(mqttReceiver, counterActionFilter);
    }

    @Override
    public int getChangingConfigurations() {
        return super.getChangingConfigurations();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    private String md5(String string) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(string.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }

        return hex.toString();
    }

    private void videoPlayEnd() {
        if (mVideoView != null) {
            mVideoView.release();
            mVideoView = null;
        }
        mHandler = null;
        finish();
    }

    private double getCurrentSpan(MotionEvent event) {
        float disX = Math.abs(event.getX(0) - event.getX(1));
        float disY = Math.abs(event.getY(0) - event.getY(1));
        return Math.sqrt(disX * disX + disY * disY);
    }

    private float getFocusX(MotionEvent event) {
        float xPoint0 = event.getX(0);
        float xPoint1 = event.getX(1);
        return (xPoint0 + xPoint1) / 2;
    }

    private float getFocusY(MotionEvent event) {
        float yPoint0 = event.getY(0);
        float yPoint1 = event.getY(1);
        return (yPoint0 + yPoint1) / 2;
    }

    public void savebitmap(Bitmap bitmap) {
        File appDir = new File(Environment.getExternalStorageDirectory(), "com.ksy.recordlib.demo.demo");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void back(View v) {
        logoutLive();
    }

    private void logoutLive() {
        EasyAlertDialogHelper.createOkCancelDiolag(TextureVideoActivity.this, null, getString(R.string.logout_confirm),
                getString(R.string.leave), getString(R.string.cancel), true,
                new EasyAlertDialogHelper.OnDialogActionListener() {
                    @Override
                    public void doCancelAction() {
                    }

                    @Override
                    public void doOkAction() {
                        if (mVideoView != null) {
                            mVideoView.release();
                            mVideoView = null;
                        }
                        mHandler = null;
                        billingDelegate = new BillingDelegate(TextureVideoActivity.this);
                        String param = AppUtil.getJoinMeetingParam(AppUtil.mUser.getPhone(), AppUtil.mUser.getUsername(), mMeetingID, mRoomID, 2, 3);
                        SampleApplicationLike.joinOrExitMeeting(billingDelegate, AppUtil.mUser.getToken(), param);
                        Map<String, String> map = new HashMap<>();
                        map.put("name", AppUtil.mUser.getUsername());
                        map.put("phone", AppUtil.mUser.getPhone());
                        Gson gson = new Gson();
                        if (mqttBinder == null || mqttBinder.isClientEmpty()) {
                            return;
                        }
                        mqttBinder.publish("/meetting/handspeak/cancel/" + mRoomID, gson.toJson(map));
                        finish();
                    }
                }).show();
    }

    private BroadcastReceiver mqttReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String type = intent.getStringExtra("type");
            if (type.equals("hand_resp")) {
                //showToast("hand_resp");
//                String waitNum = intent.getStringExtra("wait_num");
//                if (waitNum.equals("0")) {//临时参加会议
//                    showToast("正在加入会议");
//                    ChatRoomActivity.start(TextureVideoActivity.this, mRoomID,mMeetingID, false,true,mDataSource);
//                    finish();
//                } else {
//                    showToast("您前面还有" + waitNum + "人在等待");
//                }
                int status = intent.getIntExtra("status", 0);
                if (status == 1) {//临时参加会议
                    showToast("正在加入会议");
                    ChatRoomActivity.start(TextureVideoActivity.this, mRoomID, mMeetingID, false, true, mDataSource);
                    finish();
                } else if (status == 2) {
                    showToast("主持人未同意你的请求");
                }
            } else if (type.equals("upgrade_resp")) {//升级成功后参加会议
                int status = intent.getIntExtra("status", -1);
                if (status == 1) {
                    showToast("主持人同意你的升级请求");
                    ChatRoomActivity.start(TextureVideoActivity.this, mRoomID, mMeetingID, false, false, mDataSource);
                    finish();

                } else if (status == 0) {
                    showToast("主持人未同意你的升级请求");
                }
            }
        }

    };

    @Event({R.id.ll_statement, R.id.ll_statement_cancel, R.id.ll_upgrade_permissions, R.id.back_arrow, R.id.ll_upgrade_permissions_cancel})
    private void onViewClick(View v) {
        switch (v.getId()) {
            case R.id.ll_statement:
                statement();

                break;
            case R.id.ll_statement_cancel:
                statementCancel();
                break;
            case R.id.ll_upgrade_permissions:
                upgradePermissions();
                break;
            case R.id.ll_upgrade_permissions_cancel:
                upgradePermissionsCancel();
                break;
            case R.id.back_arrow:
                logoutLive();
                break;
        }
    }

    private void upgradePermissionsCancel() {
        Map<String, String> map = new HashMap<>();
        map.put("name", AppUtil.mUser.getUsername());
        map.put("phone", AppUtil.mUser.getPhone());
        Gson gson = new Gson();
        if (mqttBinder == null || mqttBinder.isClientEmpty()) {
            return;
        }
        mqttBinder.publish("/meetting/in/cancel/" + mRoomID, gson.toJson(map));
        showToast("取消升级申请已发送");

    }

    private void upgradePermissions() {
        Map<String, String> map = new HashMap<>();
        map.put("name", AppUtil.mUser.getUsername());
        map.put("phone", AppUtil.mUser.getPhone());
        Gson gson = new Gson();
        if (mqttBinder == null || mqttBinder.isClientEmpty()) {
            // showToast("123");
            return;
        }
        mqttBinder.publish("/meetting/in/apply/" + mRoomID, gson.toJson(map));
        mqttBinder.subscribe("/meetting/in/resp/" + mRoomID);
        showToast("升级申请已发送");
    }

    private void statementCancel() {
        Map<String, String> map = new HashMap<>();
        map.put("name", AppUtil.mUser.getUsername());
        map.put("phone", AppUtil.mUser.getPhone());
        Gson gson = new Gson();
        if (mqttBinder == null || mqttBinder.isClientEmpty()) {
            return;
        }
        mqttBinder.publish("/meetting/handspeak/cancel/" + mRoomID, gson.toJson(map));
        showToast("取消发言申请已发送");
        mStatementLl.setVisibility(View.VISIBLE);
        mStatementCancel.setVisibility(View.GONE);
    }

    private void statement() {
        Map<String, String> map = new HashMap<>();
        map.put("name", AppUtil.mUser.getUsername());
        map.put("phone", AppUtil.mUser.getPhone());
        Gson gson = new Gson();
        if (mqttBinder == null || mqttBinder.isClientEmpty()) {
            return;
        }
        mqttBinder.publish("/meetting/handspeak/apply/" + mRoomID, gson.toJson(map));
        mqttBinder.subscribe("/meetting/handspeak/resp/" + AppUtil.mUser.getPhone());
        showToast("发言申请已发送");
        mStatementLl.setVisibility(View.GONE);
        mStatementCancel.setVisibility(View.VISIBLE);
    }

    /**
     * 再按一次退出系統
     */
    private long exitTime = 0;

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                showToast("再按一次挂断");
                exitTime = System.currentTimeMillis();
            } else {
                logoutLive();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void sendMeetingRecord(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("phone", mRoomID);
        map.put("type", new Integer(2));
        map.put("direct", new Integer(1));
        map.put("status", new Integer(0));
        Gson gson = new Gson();
        /// Log.v("--name--11", gson.toJson(map));
        // Log.i("--name--22", gson.toJson(map));
        /// Toast.makeText(AVChatActivity.this, gson.toJson(map), Toast.LENGTH_LONG).show();
        dialingDelegate.callRecord(gson.toJson(map), AppUtil.mUser.getToken(), SEND_RECORD);
    }

    @Override
    public void success(String result, byte flag) {
        super.success(result, flag);
        if (flag == GET_OTHER_NAME_MEETING) {
            getOtherNameMeetingSuccess(result);
        } else if (flag == SEND_RECORD) {
            Intent intent = new Intent(AppConstant.CALL_RECORD_RELOAD);
            sendBroadcast(intent);
        }
    }

    private void getOtherNameMeetingSuccess(String result) {
        try {
            JSONObject obj = new JSONObject(result);
            Log.e("remote_name", obj.optString("remote_name"));
            sendMeetingRecord(obj.optString("remote_name"));
        } catch (JSONException e) {
        }
    }
}
